﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using CustomControls;
using DataAccess;
using Model;
using Model.EntityModel;
using Person = Model.EntityModel.Person;
using Actor = Model.EntityModel.Actor;

namespace Project
{
    /// <summary>
    /// Interaction logic for RegisterDeclarationContent.xaml
    /// </summary>
    public partial class RegisterDeclarationContent : UserControl
    {
        private long ComplaintId;
        private bool isEnabledPersonalInfo;
        private Person Victim;
        private Person Complainant;
        private Person Informer;
        private Person Aggressor;
        private Person Witness;
        private DateTime datetime;
        private ObservableCollection<ShowableQuestion> _showableQuestions; 
        public ObservableCollection<ShowableQuestion> ShowableQuestions{ get { return _showableQuestions; } set { _showableQuestions = value; } }

        public RegisterDeclarationContent()
        {
            InitializeComponent();
            ShowableQuestions = new ObservableCollection<ShowableQuestion>();
            cboxActorCountry.ItemsSource = GetCountryList();
            cboxActorCountry.SelectedValue = "Bolivia";
            DisablePersonalInfo();
            tbActorAddress.DeactivateBlankValidation();
            tbActorZone.DeactivateBlankValidation();
            tbActorPhone.DeactivateBlankValidation();
            tbActorPhone.AddValitationRule(new PhoneValidationRule());
            datetime = DateTime.Now;
            lblCurrentTime.Content = datetime.ToShortTimeString();
            lblTodayDate.Content = datetime.ToShortDateString();
            lblRegistrationDate.Content = lblTodayDate.Content;
            SearchComplaint sc = new SearchComplaint();
            sc.listViewComplaints.MouseDoubleClick+=new MouseButtonEventHandler(listViewComplaints_MouseDoubleClick);
            SearchPopUp.Content = sc;
            SearchPopUp.Show();
            SearchPopUp.CloseButtonVisibility = Visibility.Hidden;
            Informer = new Person();
            Witness = new Person();
            Informer.Nationality = "Bolivia";
            Witness.Nationality = "Bolivia";
            tbQuestion.AddValitationRule(new LenghtValidationRule(15));
            tbResponse.AddValitationRule(new LenghtValidationRule(15));
            gridAddQuestion.Height = 0;
            listBoxQuestions.DataContext = this;
        }

        public void listViewComplaints_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if ((sender as ListView).SelectedItem != null)
            {
                ComplaintId = ((sender as ListView).SelectedItem as ComplaintInformation).NumberOfCase;
                lblCaseNumber.Content = ComplaintId;
                lblCaseNum.Content = ComplaintId;
                Victim = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Victima", ComplaintId).Person;
                Aggressor = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Agresor", ComplaintId).Person;
                Complainant = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Denunciante", ComplaintId).Person;
                lblAggressor.Content = Aggressor.Name + " " + Aggressor.PaternalName + " " + Aggressor.MaternalName;
                SearchPopUp.Close();
            }
        }

        private List<string> GetCountryList()
        {
            List<string> cultureList = new List<string>();
            CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
            foreach (CultureInfo culture in cultures)
            {
                if (!culture.IsNeutralCulture && culture.LCID != 0x7F)
                {
                    RegionInfo region = new RegionInfo(culture.LCID);
                    if (!(cultureList.Contains(region.DisplayName)))
                        cultureList.Add(region.DisplayName);
                }
            }
            var sortedList = (from culture in cultureList
                              orderby culture
                              select culture).ToList();
            return sortedList;
        }

        public void DisablePersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if(!(control is Label))
                    (control as Control).IsEnabled = false;
            }
            isEnabledPersonalInfo = false;
        }

        public void EnablePersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if (!(control is Label))
                 
                    (control as Control).IsEnabled = true;
            }
            isEnabledPersonalInfo = true;
        }

        public void SetReadOnlyPersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if(control is MaskTextBox)
                    (control as MaskTextBox).IsReadOnly = true;
                if (control is ValidationComboBox)
                    (control as ValidationComboBox).IsHitTestVisible = false;
                if (control is ComboBox)
                    (control as ComboBox).IsHitTestVisible = false;
            }
            tbActorWorkPlace.IsReadOnly = false;
        }

        public void UnSetReadOnlyPersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if (control is MaskTextBox)
                    (control as MaskTextBox).IsReadOnly = false;
                if (control is ValidationComboBox)
                    (control as ValidationComboBox).IsHitTestVisible = true;
                if (control is ComboBox)
                    (control as ComboBox).IsHitTestVisible = true;
            }
        }

        public void SetPersonalInfoContext(Person person)
        {
            if (person != null)
            {
                tbActorName.Text = person.Name;
                tbActorLastName.Text = person.PaternalName;
                tbActorMiddleName.Text = person.MaternalName;
                tbActorCI.Text = person.CiPassport == 0 ? "" : person.CiPassport.ToString();
                tbActorAddress.Text = person.Address;
                tbActorPhone.Text = person.Phone;
                tbActorZone.Text = person.Zone;
                tbActorWorkPlace.Text = person.WorkPlace;
                cboxActorCountry.SelectedValue = person.Nationality;
                cbActorCivilStatus.SelectedValue = person.CivilStatus;
            }
        }

        private void rbtnVictim_Checked(object sender, RoutedEventArgs e)
        {
            if(!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Victim);
            SetReadOnlyPersonalInfo();
        }

        private void rbtnComplainant_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Complainant);
            SetReadOnlyPersonalInfo();
        }

        private void rbtnInformer_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Informer);
            UnSetReadOnlyPersonalInfo();
        }

        private void rbtnAggressor_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Aggressor);
            SetReadOnlyPersonalInfo();

        }

        private void rbtnWitness_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Witness);
            UnSetReadOnlyPersonalInfo();
        }

        private void btnRegister_Click(object sender, RoutedEventArgs e)
        {
            bool res = CheckHasErrors();
            try
            {
                if (!res)
                {
                    long actorId=0;
                    if ((bool)rbtnVictim.IsChecked)
                    {
                        var actr = (from a in Victim.Actor
                                    where a.IdComplaint == ComplaintId
                                    select a).SingleOrDefault();
                        actorId = actr.Id;
                        actr.Person.WorkPlace = tbActorWorkPlace.Text;
                        PersonAndActorDataAccess.UpdatePerson(actr.Person.CiPassport, actr.Person);
                    }
                    if ((bool)rbtnComplainant.IsChecked)
                    {
                        var actr = (from a in Complainant.Actor
                                    where a.IdComplaint == ComplaintId
                                    select a).SingleOrDefault();
                        actorId = actr.Id;
                        actr.Person.WorkPlace = tbActorWorkPlace.Text;
                        PersonAndActorDataAccess.UpdatePerson(actr.Person.CiPassport, actr.Person);
                    }
                    if ((bool)rbtnInformer.IsChecked)
                    {
                        bool exists = PersonAndActorDataAccess.PersonAlreadyExists(long.Parse(tbActorCI.Text),
                                                                                   tbActorName.Text,
                                                                                   tbActorLastName.Text,
                                                                                   tbActorMiddleName.Text);
                        if (!exists)
                        {
                            var pers = new Person();
                            pers.Id = tbActorCI.Text + DateTime.Now.Date.ToString(
                    CultureInfo.GetCultureInfo("es-ES").DateTimeFormat.ShortDatePattern);
                            pers.Name = tbActorName.Text;
                            pers.PaternalName = tbActorLastName.Text;
                            pers.MaternalName = tbActorMiddleName.Text;
                            pers.CiPassport = long.Parse(tbActorCI.Text);
                            pers.Address = tbActorAddress.Text;
                            pers.Phone = tbActorPhone.Text;
                            pers.Zone = tbActorZone.Text;
                            pers.WorkPlace = tbActorWorkPlace.Text;
                            pers.Nationality = cboxActorCountry.SelectedValue.ToString();
                            pers.CivilStatus = cbActorCivilStatus.SelectedValue.ToString();
                            pers.RegisterDate = DateTime.Now;
                            Informer = PersonAndActorDataAccess.InsertPerson(pers);
                        }
                        else
                        {
                            Informer = PersonAndActorDataAccess.GetPersonByCi(long.Parse(tbActorCI.Text));
                            Informer.WorkPlace = tbActorWorkPlace.Text;
                            PersonAndActorDataAccess.UpdatePersonWorkPlace(tbActorWorkPlace.Text, Informer.CiPassport);
                        }
                        var actor = new Actor();
                        bool actorExists = PersonAndActorDataAccess.ActorAlreadyExists(Informer.Id, ComplaintId,
                                                                                       "Informador");
                        if (!actorExists)
                        {
                            actor =
                                PersonAndActorDataAccess.InsertActor(new Actor
                                                                         {
                                                                             IdPerson = Informer.Id,
                                                                             IdComplaint = ComplaintId,
                                                                             Type = "Informador"
                                                                         });
                        }
                        else
                        {
                            actor = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Informador", ComplaintId);
                        }
                        actorId = actor.Id;
                    }
                    if ((bool)rbtnWitness.IsChecked)
                    {
                        bool exists = PersonAndActorDataAccess.PersonAlreadyExists(long.Parse(tbActorCI.Text),
                                                                                   tbActorName.Text,
                                                                                   tbActorLastName.Text,
                                                                                   tbActorMiddleName.Text);
                        if (!exists)
                        {
                            var pers = new Person();
                            pers.Id = tbActorCI.Text + DateTime.Now.Date.ToString(
                    CultureInfo.GetCultureInfo("es-ES").DateTimeFormat.ShortDatePattern);
                            pers.Name = tbActorName.Text;
                            pers.PaternalName = tbActorLastName.Text;
                            pers.MaternalName = tbActorMiddleName.Text;
                            pers.CiPassport = long.Parse(tbActorCI.Text);
                            pers.Address = tbActorAddress.Text;
                            pers.Phone = tbActorPhone.Text;
                            pers.Zone = tbActorZone.Text;
                            pers.WorkPlace = tbActorWorkPlace.Text;
                            pers.Nationality = cboxActorCountry.SelectedValue.ToString();
                            pers.CivilStatus = cbActorCivilStatus.SelectedValue.ToString();
                            pers.RegisterDate = DateTime.Now;
                            Witness = PersonAndActorDataAccess.InsertPerson(pers);
                        }
                        else
                        {
                            Witness = PersonAndActorDataAccess.GetPersonByCi(long.Parse(tbActorCI.Text));
                            Witness.WorkPlace = tbActorWorkPlace.Text;
                            PersonAndActorDataAccess.UpdatePersonWorkPlace(tbActorWorkPlace.Text, Witness.CiPassport);
                        }
                        var actor = new Actor();
                        bool actorExists = PersonAndActorDataAccess.ActorAlreadyExists(Witness.Id, ComplaintId,
                                                                                       "Testigo");
                        if (!actorExists)
                        {
                            actor =
                                PersonAndActorDataAccess.InsertActor(new Actor
                                                                         {
                                                                             IdPerson = Witness.Id,
                                                                             IdComplaint = ComplaintId,
                                                                             Type = "Testigo"
                                                                         });
                        }
                        else
                        {
                            actor = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Testigo", ComplaintId);
                        }

                        actorId = actor.Id;
                    }
                    if ((bool)rbtnAggressor.IsChecked)
                    {
                        var actr = (from a in Aggressor.Actor
                                    where a.IdComplaint == ComplaintId
                                    select a).SingleOrDefault();
                        actorId = actr.Id;
                        actr.Person.WorkPlace = tbActorWorkPlace.Text;
                        PersonAndActorDataAccess.UpdatePerson(actr.Person.CiPassport, actr.Person);
                    }

                    foreach (var declarationQuestion in ShowableQuestions)
                    {
                            DeclarationDataAccess.InsertDeclaration(new Declaration
                                                                        {
                                                                            RegistrationDate = datetime,
                                                                            ActorId = actorId,
                                                                            ComplaintId = ComplaintId,
                                                                            Question = declarationQuestion.Question,
                                                                            Answer = declarationQuestion.Answer,
                                                                            Status = false
                                                                        });
                    }
                    var style = new Style(typeof(Xceed.Wpf.Toolkit.MessageBox));
                    style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.YesButtonContentProperty, "Si"));
                    var resB = Xceed.Wpf.Toolkit.MessageBox.Show("Se registró la declaración exitosamente, Desea imprimir la declaración?",
                                                                "Exito!", MessageBoxButton.YesNo,
                                                                MessageBoxImage.Information, style);
                    if (resB == MessageBoxResult.Yes)
                    {
                        var declarations = DeclarationDataAccess.GetAllShowableDeclarations(ComplaintId);
                        foreach (var showableDeclaration in declarations)
                        {
                            if (showableDeclaration.RegistrationDate == lblRegistrationDate.Content.ToString() && showableDeclaration.DeclarantCI.ToString() == tbActorCI.Text)
                            {
                                var items = new ObservableCollection<UserControl>();
                                items.Add(new PrintDeclaration(ComplaintId, showableDeclaration.QuestionsAndAnswer));
                                var a = new PrintPreviewDialogV2(items);
                                a.ShowDialog();
                                break;
                            }
                        } 
                        
                    }
                    else
                    {
                        Xceed.Wpf.Toolkit.MessageBox.Show("Puede imprimir la declaración posteriormente, entrando a Ver Denuncias, click sobre la denuncia: Ver Declaraciones, y selecciona Ver Declaración",
                                                                "Información!", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                    UIWindowManager.CleanWindow(this);
                }
                else
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("Debe llenar todos los campos para poder continuar", "Error!");
                }
            }
            catch (Exception h)
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("Ocurrió un error inesperado mientras se trataba de registrar la declaración", "Error!");
            }
        }
        
        private bool CheckHasErrors()
        {
            bool res = false;
            foreach (var ctrl in PersonalInfo.Children)
            {
                if (ctrl is MaskTextBox)
                {
                    (ctrl as MaskTextBox).GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
                    if (Validation.GetHasError(ctrl as MaskTextBox) && (ctrl as MaskTextBox).Name != "tbQuestion" && (ctrl as MaskTextBox).Name != "tbResponse")
                        res = true;
                }
                if (ctrl is ValidationComboBox)
                {
                    (ctrl as ValidationComboBox).LostFocusEventHandler(ctrl as ValidationComboBox, null);
                    if (Validation.GetHasError(ctrl as ValidationComboBox))
                        res = true;
                }
            }
            if (!isEnabledPersonalInfo)
            {
                lblSelError.Content = "Debe seleccionar un declarante para poder registrar una declaración";
                res = true;
            }
            if (listBoxQuestions.Items.Count <= 0)
            {
                lblNoQuestionsError.Visibility = Visibility.Visible;
                res = true;
            }
            return res;
        }

        private void btnAddQuestion_Click(object sender, RoutedEventArgs e)
        {
            ShowDialogGrid();
            lblQuestionNumber.Content = listBoxQuestions.Items.Count + 1;
            if (string.IsNullOrEmpty(tbQuestion.Text) && string.IsNullOrEmpty(tbResponse.Text))
                lblQuestionERROR.Visibility = Visibility.Hidden;
            else
            {
                tbQuestion.GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
                tbResponse.GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
                if (tbQuestion.Text.Length >= 15 && tbResponse.Text.Length >= 15)
                    lblQuestionERROR.Visibility = Visibility.Hidden;
                else
                {
                    lblQuestionERROR.Visibility = Visibility.Visible;
                }
            }
        }

        private void ShowDialogGrid()
        {
            btnAddQuestion.IsHitTestVisible = false;
            tbQuestion.IsHitTestVisible = true;
            tbResponse.IsHitTestVisible = true;
            DoubleAnimation doubleAnimation = new DoubleAnimation(0, 238, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
            Storyboard st = new Storyboard();
            st.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(st, new PropertyPath("Height"));
            Storyboard.SetTargetName(st, "gridAddQuestion");
            BeginStoryboard(st);
        }

        private void HideDialogGrid()
        {
            btnAddQuestion.IsHitTestVisible = true;
            tbQuestion.IsHitTestVisible = false;
            tbResponse.IsHitTestVisible = false;
            DoubleAnimation doubleAnimation = new DoubleAnimation(238, 0, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
            Storyboard st = new Storyboard();
            st.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(st, new PropertyPath("Height"));
            Storyboard.SetTargetName(st, "gridAddQuestion");
            BeginStoryboard(st);
        }

        private void btnAddCancel_Click(object sender, RoutedEventArgs e)
        {
            HideDialogGrid();
            Validation.ClearInvalid(tbQuestion.GetBindingExpression(MaskTextBox.TextProperty));
            Validation.ClearInvalid(tbResponse.GetBindingExpression(MaskTextBox.TextProperty));
            if (tbQuestion.Text.Length >= 15 && tbResponse.Text.Length >= 15)
                lblQuestionERROR.Visibility = Visibility.Hidden;
        }

        private void btnAddSuccess_Click(object sender, RoutedEventArgs e)
        {
            tbQuestion.GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
            bool hasError = Validation.GetHasError(tbQuestion) || Validation.GetHasError(tbResponse);
            if (!hasError)
            {
                ShowableQuestions.Add(new ShowableQuestion
                {
                    Question = tbQuestion.Text,
                    Answer = tbResponse.Text,
                    NumberOfQuestion = listBoxQuestions.Items.Count+1
                });
                //listBoxQuestions.UpdateLayout();
                HideDialogGrid();
                tbQuestion.Text = "";
                tbResponse.Text = "";
                Validation.ClearInvalid(tbQuestion.GetBindingExpression(MaskTextBox.TextProperty));
                Validation.ClearInvalid(tbResponse.GetBindingExpression(MaskTextBox.TextProperty));
                lblQuestionERROR.Visibility = Visibility.Hidden;
                lblNoQuestionsError.Visibility = Visibility.Hidden;
            }
            else
            {
                lblQuestionERROR.Visibility = Visibility.Visible;
            }
        }


        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            var style = new Style(typeof(Xceed.Wpf.Toolkit.MessageBox));
            style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.YesButtonContentProperty, "Si"));
            var res = Xceed.Wpf.Toolkit.MessageBox.Show("Esta seguro(a) de que desea eliminar la pregunta de la lista?", "Confirmar Accion!", MessageBoxButton.YesNo, MessageBoxImage.Warning, style);
            if (res == MessageBoxResult.Yes)
            {
                Button cmd = (Button)sender;
                if (cmd.DataContext is ShowableQuestion)
                {
                    ShowableQuestion deleteme = (ShowableQuestion)cmd.DataContext;
                    ShowableQuestions.Remove(deleteme);
                    int i = 1;
                    foreach (var lbItem in ShowableQuestions)
                    {
                        lbItem.NumberOfQuestion = i;
                        i++;
                    }
                    listBoxQuestions.UpdateLayout();
                    listBoxQuestions.Items.Refresh();
                }
            }
        }

        private List<ListBoxItem> GetListBoxItems(ListBox listBox)
        {
            List<ListBoxItem> items = new List<ListBoxItem>();
            while (listBox.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
            { }
                foreach (var item in ShowableQuestions)
                {
                    ListBoxItem itemToAdd = listBox.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem;
                    if(itemToAdd!=null)
                        items.Add(itemToAdd);
 
                }
            return items;
        }

        private void UpSizeListBoxAndGridForPrint()
        {
            ContentGrid.UpdateLayout();
            this.UpdateLayout();
            listBoxQuestions.UpdateLayout();
            var listboxItems = GetListBoxItems(listBoxQuestions);
            double count = 0;
            foreach (ListBoxItem listItem in listboxItems)
            {
                count += listItem.ActualHeight;
            }
            listBoxQuestions.Height += 160;
            //if (count > listBoxQuestions.Height)
            //{
                listBoxQuestions.Height = count+35;
                ContentGrid.Height += count-230;
                this.Height = ContentGrid.Height;
           // }
            ContentGrid.UpdateLayout();
            this.UpdateLayout();
            listBoxQuestions.ScrollIntoView(listBoxQuestions.Items[0]);
            listBoxQuestions.UpdateLayout();
        }
    }
}
